

template <typename T> 
class StackYo
{
		
public:
	StackYo()
		:m_Length(1), m_Size(0)
	{	
		m_pData = new T[m_Length];		
		memset(m_pData, 0, sizeof(T)*m_Length);
	}
	~StackYo()
	{
		delete m_pData;		
	}

public:	
	inline bool isEmpty() { return (m_Size == 0); }
	inline long long size(){ return m_Size; }
	void push(T &item)
	{
		if (m_Size == m_Length)
			resize(m_Length * 2);
		m_pData[m_Size++] = item;
	}

	// Note: Undefined behavior on empty stack, Check for isEmpty before pop
	T& pop()
	{	
		// When non zero size reaches quarter of length, reduce stack size by half
		if (m_Size - 1 > 0 && (m_Size - 1) == (m_Length / 4))
			resize(m_Length / 2);
		return m_pData[--m_Size];
	}
protected:
	void resize(int newLength)
	{
		if (m_Length != newLength)
		{
			T* pTemp = new T[newLength];
			int safeLength = (newLength > m_Length) ? m_Length : newLength;
			for (int i = 0; i < safeLength; ++i)
				pTemp[i] = m_pData[i];

			delete m_pData;
			m_pData = pTemp;
			newLength = m_Length;
		}
	}

private:
	long long m_Length;
	long long m_Size;
	T *m_pData;	
};